/*
 * Lucas McDaniel
 * GSoC '11
 * HoneyViz
 * 
 * This simple class is used to organize information about each event.  Events 
 * are broken up by location (determined during data import), date (day), and 
 * type of event (MD5 hash).  Each event has a quantity detailing how many times 
 * that type of event has been seen at that location on that day.
 * 
 * Cloneable, Comparable
 */

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.w3c.dom.*;

public class DataElement {
    
    public String name;
    public Date time;
    public int count;
    double longitude, latitude;
    
    public DataElement(DataElement e)
    {
        time = e.time;
        name = e.name;
        count = e.count;
        longitude = e.longitude;
        latitude = e.latitude;
    }
    
    public DataElement(String name, Date time, int count, double latitude, double longitude)
    {
        this.name = name;
        this.time = time;
        this.count = count;
        this.latitude = latitude;
        this.longitude = longitude;
    }
    
    public DataElement(Element e)
    {
        name = getDataElement(e, "category");
        longitude = Double.parseDouble(getDataElement(e, "longitude"));
        latitude = Double.parseDouble(getDataElement(e, "latitude"));
        count = Integer.parseInt(getDataElement(e, "count"));
        DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        try
        {
            time = (Date)format.parse(getDataElement(e, "time"));
        }
        catch (ParseException pe)
        {
            pe.printStackTrace();
        }
    }
    
    public String getDataElement(Element e, String val)
    {
        return e.getElementsByTagName(val).item(0).getChildNodes().item(0).getNodeValue();
    }
    
    public DataElement makeNew()
    {
        return new DataElement(this);
    }
    
    public boolean isSame(DataElement e)
    {
        if (name.compareTo(e.name)!=0)
            return false;
        if (time.compareTo(e.time)!=0)
            return false;
        if (count != e.count)
            return false;
        if (latitude != e.latitude)
            return false;
        if (longitude != e.longitude)
            return false;
        return true;
    }
    
    /*
     * If sName or sDate are null, or sLate and sLon are 0 then disregard
     * search criteria.  This is used to determine relative location in 
     * search parameters as well as if DataElement exists in search 
     * parameters.
     */
    
    public int isInSearchParameters(String sName, Date sDate, double sLat, double sLon)
    {
        int rtnVal = 0;
        if (sName!=null)
        {
            rtnVal = sName.compareTo(name);
            if (rtnVal!=0)
            {
                return rtnVal;
            }
        }
        if (sDate!=null)
        {
            rtnVal = sDate.compareTo(time);
            if (rtnVal!=0)
            {
                return rtnVal;
            }
        }
        if (sLon!=0 || sLat!=0)
        {
            double tmp = sLat - latitude;
            if (tmp != 0.0)
            {
                return tmp>0?1:-1;
            }
            tmp = sLon - longitude;
            if (tmp != 0.0)
            {
                return tmp>0?1:-1;
            }
        }
        return rtnVal;
    }
    
    public int compareTo(DataElement DE)
    {
        int cmpVal = DE.name.compareTo(name);
        if (cmpVal!=0)
            return cmpVal;
        cmpVal = DE.time.compareTo(time);
        if (cmpVal!=0)
            return cmpVal;
        cmpVal = DE.latitude < latitude ? -1 : (DE.latitude > latitude) ? 1 : 0;
        if (cmpVal!=0)
            return cmpVal;
        return DE.longitude < longitude ? -1 : (DE.longitude > longitude) ? 1 : 0;
    }
    
    public String toString()
    {
        return this.name + "\t" + this.time + "\t" + this.count + "\t" + this.latitude + "\t" + this.longitude;
    }
}
